#include "stdafx.h"
#include "Protocol.h"


CProtocol::CProtocol()
{
}


CProtocol::~CProtocol()
{
}

uint CProtocol::Run()
{
    book->Load( "book.fbk" );
    SetDefaultPosition();
    char input[65536] = "";
    char first[256] = "";
    while( ( strcmp(input,"quit"))  )
    {
        gets_s( input, 65535 );
        if ( !strcmp(input,"isready")) 
            IsReady();
        else if ( !strcmp(input,"uci")) 
            UCI();
        else if ( !strcmp(input,"stop")) 
            Stop();
        else if ( !strcmp(input,"perft")) 
            Perft();
        else if ( strstr (input,"position") )
            Position( input );
        else if ( strstr (input,"go") )
            Go( input );
        else if ( strstr( input, "createbook" ) )
            CreateBook( input+11 );
    }
    QuitPrepare();
    return 0;
}

uint CProtocol::SetDefaultPosition()
{
    color = fen->Set( board, "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
    return 0;
}

uint CProtocol::UCI()
{
    // system("color 6");
    cout << "id name Freelancer 1.1.0"<<endl;
    cout << "id author Felix Shutenko"<<endl;
    cout << "uciok"<<endl;
    return 0;
}

uint CProtocol::QuitPrepare()
{
    Stop();
    return 0;
}

uint CProtocol::IsReady()
{
    cout << "readyok" << endl;
    return 0;
}

uint CProtocol::Stop()
{
    perft->SetCtrl( STOP );
    while( !perft->Done() ) Sleep( 1 );
    return 0;
}

uint CProtocol::Perft()
{
    
    hPerftThread = _beginthread(&CProtocol::_RunPerft_wrapper, 0, static_cast<void*>(this));
    // hThread = (HANDLE)_beginthread(_RunPerft,0,NULL);
    // _RunPerft();
    return 0;
}

uint CProtocol::_RunPerft()
{
    uint64 ply = 0;
    if ( !perft->Done() ) {
        cout << "Perft is busy!"<<endl;
        return -1;
    }
    cout << "Run Perft" << endl;
    perft->SetCtrl( FREE );
    ply = perft->Start( board, 6 );
    cout << "Moves = " << ply <<endl;
    return 0;
}

uint CProtocol::Position( char * line )
{   
    Stop();
    CMoveList   list[1];
    CMove       move[1];
    char * fenstring;
    char * movesstring;
    if (strstr (line,"startpos"))
        fen->Set( board, "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
    if ( fenstring = strstr (line,"fen"))
    {
        fenstring += 4;
        fen->Set( board, fenstring);
    }
    if ( movesstring = strstr (line,"moves"))
    {
        char m[256];

        movesstring += 6;
        istringstream iss(movesstring);
        while(iss >> m) {
            // cout << m << endl;
            list->Reset();
            move->GenAll( board, list, board->GetColor() );
            list->Start();
            uint found_move = 0;
            while( !list->IsEmpty() && !found_move )
            {
                char ms[256];
                move->ToString(list->GetMove(), ms );
                if ( !strcmp(m, ms ) ) 
                    found_move = list->GetMove();
                list->Next();
            }
            if ( !found_move ) {
                cout << "Cannot find move " << m <<endl; 
                list->Print();
                return 1;
            }
            move->Do( board, found_move );
        }
    }
    // board->Print();
    cout << "Draw = " << board->IsDraw() <<endl;
    return 0;
}

uint CProtocol::Go( char * line )
{   
    uint mymove;
    CMoveList   list[1];
    mymove = book->GetMove( board );
    if (mymove) {
        cout << "bestmove ";
        list->PrintMove( mymove );
    } else cout << "bestmove a1a1"<<endl;
    cout << endl;
    return 0;
}

uint CProtocol::CreateBook( char * line )
{
    char inputname[1024];
    char outputname[1024];
    uint min_elo = 0;
    uint max_ply = 0;
    istringstream iss(line);
    iss >> inputname;
    iss >> outputname;
    iss >> min_elo;
    iss >> max_ply;
    book->Create( inputname, outputname, min_elo, max_ply );
    return 0;
}